﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Twodi.Interfaces;
using Microsoft.Xna.Framework;
using Twodi.Aspect.Args;
using Twodi.Enums;

namespace Twodi.Aspect.Implemented
{
    /// <summary>
    /// 
    /// </summary>
    public class LimitedAspect : DependentAspect<ILimitedAspect>, ILimited
    {
        private Rectangle limits = Rectangle.Empty;

        public LimitedAspect(ILimitedAspect component)
            : base(component)
        {
            Component.PositionProperties.PositionChanged += new EventHandler<Args.PositionChangedEventArgs>(CheckPosition);
        }

        void CheckPosition(object sender, Args.PositionChangedEventArgs e)
        {
            if (Limits == Rectangle.Empty) return;
 
            if (!this.Limits.Intersects(this.Component.BoundsProperties.Bounds))
            {
                if (this.Component.BoundsProperties.Bounds.Left > this.Limits.Width)
                {
                    onOutsideLimits(new OutsideLimitsEventArgs(Direction.East,this.Limits));
                }
                else if (this.Component.BoundsProperties.Bounds.Right < this.Limits.X)
                {
                    onOutsideLimits(new OutsideLimitsEventArgs(Direction.West, this.Limits));
                }
                else if (this.Component.BoundsProperties.Bounds.Top > this.Limits.Height)
                {
                    onOutsideLimits(new OutsideLimitsEventArgs(Direction.South, this.Limits));
                }
                else if (this.Component.BoundsProperties.Bounds.Bottom < this.Limits.Y)
                {
                    onOutsideLimits(new OutsideLimitsEventArgs(Direction.North, this.Limits));
                }
            }
            else 
            {
                if (this.Component.BoundsProperties.Bounds.Right > this.Limits.Width)
                {
                    onTouchLimitsLimits(new OutsideLimitsEventArgs(Direction.East, this.Limits));
                }
                else if (this.Component.BoundsProperties.Bounds.Left < this.Limits.X)
                {
                    onTouchLimitsLimits(new OutsideLimitsEventArgs(Direction.West, this.Limits));
                }
                else if (this.Component.BoundsProperties.Bounds.Bottom > this.Limits.Height)
                {
                    onTouchLimitsLimits(new OutsideLimitsEventArgs(Direction.South, this.Limits));
                }
                else if (this.Component.BoundsProperties.Bounds.Top  < this.Limits.Y)
                {
                    onTouchLimitsLimits(new OutsideLimitsEventArgs(Direction.North, this.Limits));
                }
            }
        }

        public Rectangle Limits
        {
            get { return limits; }
            set { OnPropertyChanged<Rectangle>("Limits", ref limits, value); }
        }

        public event EventHandler LimitsChanged;

        public event EventHandler<OutsideLimitsEventArgs> OutsideLimits;

        public event EventHandler<OutsideLimitsEventArgs> TouchLimits;

        protected void onLimitsChanged(EventArgs e)
        {
            if (LimitsChanged != null) LimitsChanged(this, e);
        }

        protected void onOutsideLimits(OutsideLimitsEventArgs e)
        {
            if (OutsideLimits != null) OutsideLimits(this, e);
        }

        protected void onTouchLimitsLimits(OutsideLimitsEventArgs e)
        {
            if (TouchLimits != null) TouchLimits(this, e);
        }

    }
}
